bitkeeper revision 1.1108.37.1 (4108f395VJ6nDz3Ag7FW0LiNkvflog)
authortw275@labyrinth.cl.cam.ac.uk <tw275@labyrinth.cl.cam.ac.uk>
Thu, 29 Jul 2004 12:54:45 +0000 (12:54 +0000)
committertw275@labyrinth.cl.cam.ac.uk <tw275@labyrinth.cl.cam.ac.uk>
Thu, 29 Jul 2004 12:54:45 +0000 (12:54 +0000)
More work on Domain Creation Wizzard.

Works well

tools/python/xen/sv/CreateDomain.py
tools/python/xen/sv/DomList.py
tools/python/xen/sv/HTMLBase.py
tools/python/xen/sv/Wizard.py

index a3b541d3fb99fcc943d02b56a4d09bb9abdec911..b4fd52f0e8f8860bd5fe66277d65ff0e6b6a5b8e 100644 (file)
@@ -2,7 +2,7 @@ from xen.sv.Wizard import *
 from xen.sv.util import *
 from xen.sv.GenTabbed import PreTab
 
-from xen.xm.create import make_config
+from xen.xm.create import make_config, OptVals
 
 from xen.xend.XendClient import server
 
@@ -22,94 +22,108 @@ class CreatePage0( Sheet ):
 
     def __init__( self, urlWriter ):
         Sheet.__init__( self, urlWriter, "General", 0 )
-        self.addControl( InputControl( 'name', 'VM Name', 'VM Name:' ) )
-        self.addControl( InputControl( 'memory', '64', 'Memory (Mb):' ) )
-        self.addControl( InputControl( 'cpu', '0', 'CPU:' ) )
+        self.addControl( InputControl( 'name', 'VM Name', 'VM Name:', "[\\w|\\S]+", "You must enter a name in this field" ) )
+        self.addControl( InputControl( 'memory', '64', 'Memory (Mb):', "[\\d]+", "You must enter a number in this field" ) )
+        self.addControl( InputControl( 'cpu', '0', 'CPU:', "[\\d]+", "You must enter a number in this feild" ) )
                         
 class CreatePage1( Sheet ):
 
     def __init__( self, urlWriter ):
         Sheet.__init__( self, urlWriter, "Setup Kernel Image", 1 )
-        self.addControl( InputControl( 'builder', 'linux', 'Kernel Type:' ) )
-        self.addControl( InputControl( 'kernel', '/boot/vmlinuz-2.4.26-xenU', 'Kernel Image:' ) )
-        self.addControl( InputControl( 'extra', '', 'Kernel Command Line Parame:' ) )
+        self.addControl( ListControl( 'builder', [('linux', 'Linux'), ('netbsd', 'NetBSD')], 'Kernel Type:' ) )
+        self.addControl( FileControl( 'kernel', '/boot/vmlinuz-2.4.26-xenU', 'Kernel Image:' ) )
+        self.addControl( InputControl( 'extra', '', 'Kernel Command Line Parameters:' ) )
 
 class CreatePage2( Sheet ):
 
     def __init__( self, urlWriter ):
        Sheet.__init__( self, urlWriter, "Setup Virtual Block Device", 2 )
-        self.addControl( InputControl( 'num_vbds', '1', 'Number of VBDs:' ) )
+        self.addControl( InputControl( 'num_vbds', '1', 'Number of VBDs:', '[\\d]+', "You must enter a number in this field" ) )
 
 class CreatePage3( Sheet ):
 
     def __init__( self, urlWriter ):
         Sheet.__init__( self, urlWriter, "Setup Virtual Block Device", 3 )
         
-    def write_BODY( self, request ):
+    def write_BODY( self, request, err ):
+        if not self.passback: self.parseForm( request )
+    
        previous_values = sxp2hash( string2sxp( self.passback ) ) #get the hash for quick reference
+        
         num_vbds = previous_values.get( 'num_vbds' )
         
         for i in range( int( num_vbds ) ):
-            self.addControl( InputControl( 'vbd%s_dom0' % i, '/dev/sda%i' % i, 'Device %s name:' % i  ) )
-            self.addControl( InputControl( 'vbd%s_domU' % i, '/dev/sda%i' % i, 'Virtualized device %s:' % i ) )
-            self.addControl( InputControl( 'vbd%s_mode' % i, 'w', 'Device %s mode:' % i ) )
+            self.addControl( InputControl( 'vbd%s_dom0' % i, 'phy:sda%s' % str(i + 1), 'Device %s name:' % i  ) )
+            self.addControl( InputControl( 'vbd%s_domU' % i, 'sda%s' % str(i + 1), 'Virtualized device %s:' % i ) )
+            self.addControl( ListControl( 'vbd%s_mode' % i, [('w', 'Read + Write'), ('r', 'Read Only')], 'Device %s mode:' % i ) )
             
         self.addControl( InputControl( 'root', '/dev/sda1', 'Root device (in VM):' ) )
         
-        Sheet.write_BODY( self, request )
+        Sheet.write_BODY( self, request, err )
                 
 class CreatePage4( Sheet ):
 
     def __init__( self, urlWriter ):        
-        Sheet.__init__( self, urlWriter, "Network settings", 4 )  
+        Sheet.__init__( self, urlWriter, "Network settings", 4 )
+        self.addControl( ListControl( 'dhcp', [('off', 'No'), ('dhcp', 'Yes')], 'Use DHCP:' ) )
         self.addControl( InputControl( 'hostname', 'hostname', 'VM Hostname:' ) )
         self.addControl( InputControl( 'ip_addr', '1.2.3.4', 'VM IP Address:' ) )
         self.addControl( InputControl( 'ip_subnet', '255.255.255.0', 'VM Subnet Mask:' ) ) 
         self.addControl( InputControl( 'ip_gateway', '1.2.3.4', 'VM Gateway:' ) )           
-         
+        self.addControl( InputControl( 'ip_nfs', '1.2.3.4', 'NFS Server:' ) )  
+                 
 class CreateFinish( Sheet ):
 
     def __init__( self, urlWriter ):
         Sheet.__init__( self, urlWriter, "All Done", 5 )
         
-    def write_BODY( self, request ):
-       fin_sxp = string2sxp( self.passback )
+    def write_BODY( self, request, err ):
     
-        xend_sxp = self.translate_sxp( fin_sxp )
+        if not self.passback: self.parseForm( request )
         
-        pt = PreTab( sxp2prettystring( xend_sxp ) )
-        pt.write_BODY( request )
+        xend_sxp = self.translate_sxp( string2sxp( self.passback ) )
         
-        server.xend_domain_create( xend_sxp )
-       
+        dom_sxp = server.xend_domain_create( xend_sxp )
+        
+        pt = PreTab( sxp2prettystring( dom_sxp ) )
+        pt.write_BODY( request )
+
         request.write( "<input type='hidden' name='passback' value=\"%s\"></p>" % self.passback )
         request.write( "<input type='hidden' name='sheet' value='%s'></p>" % self.location )
     
     def translate_sxp( self, fin_sxp ):
        fin_hash = ssxp2hash( fin_sxp )
     
+        def get( key ):
+            ret = fin_hash.get( key )
+            if ret:
+                return ret
+            else:
+                return ""
+        
        vals = OptVals()
         
-        setattr(vals, "name",  fin_hash.get( 'name' ) )
-        setattr(vals, "memory", fin_hash.get( 'memory' ) )
-        setattr(vals, "cpu",   fin_hash.get( 'cpu' ) )
+        vals.name =    get( 'name' )
+        vals.memory =  get( 'memory' )
+        vals.cpu =     get( 'cpu' )
         
-        setattr(vals, "builder",       fin_hash.get( 'builder' ) )        
-        setattr(vals, "kernel",        fin_hash.get( 'kernel' ) )
-       setattr(vals, "root",           fin_hash.get( 'root' ) )
-        setattr(vals, "extra",                 fin_hash.get( 'extra' ) ) 
+        vals.builder =  get( 'builder' )       
+        vals.kernel =   get( 'kernel' )
+       vals.root =     get( 'root' )
+        vals.extra =   get( 'extra' )
+        
+        #setup vbds
         
         vbds = []
         
-        for i in range( int( fin_hash.get( 'num_vbds' ) ) ):
-            vbds.append( ( fin_hash.get('vbd%s_domU' % i ), fin_hash.get( 'vbd%s_dom0' % i ), fin_hash.get( 'vbd%s_mode' % i ) ) )
+        for i in range( int( get( 'num_vbds' ) ) ):
+            vbds.append( ( get( 'vbd%s_dom0' % i ), get('vbd%s_domU' % i ), get( 'vbd%s_mode' % i ) ) )
         
         vals.disk = vbds    
             
-        vals.pci = []
+        #misc crap
         
-        vals.vif = []
-        vals.nics = 1
+        vals.pci = []
         
         vals.blkif = None
         vals.netif = None
@@ -117,14 +131,18 @@ class CreateFinish( Sheet ):
         vals.console = None
         vals.ramdisk = None
         
-        #todo: setup ip addr stuff
+        #setup vifs
         
-        vals.cmdline_ip = None
+        vals.vif = []
+        vals.nics = 1
+                
+        ip =   get( 'ip_addr' )
+        nfs =  get( 'ip_nfs' )
+        gate = get( 'ip_gateway' )
+        mask = get( 'ip_subnet' )
+        host = get( 'hostname' )
+        dhcp = get( 'dhcp' )
         
-        return make_config( vals )
-
+        vals.cmdline_ip = "%s:%s:%s:%s:%s:eth0:%s" % (ip, nfs, gate, mask, host, dhcp)
         
-class OptVals:
-    """Class to hold option values.
-    """
-    pass
\ No newline at end of file
+        return make_config( vals )
index 145016cdedc134235c60ba63c71d05507a399988..faed020b05506c19ed78866066a782c4ac222da6 100755 (executable)
@@ -16,8 +16,9 @@ class DomList( HTMLBase ):
        return self.write_BODY( request, head=True, long=False ) 
 
     def write_BODY( self, request, head=True, long=True ):
-    
-        domains = server.xend_domains()
+        
+        domains = map(int, server.xend_domains())
+        domains.sort()
     
         request.write( "\n<table style='border:0px solid white' cellspacing='0' cellpadding='0' border='0' width='100%'>\n" )
         
index 07adfab76daff9f5626fd3a968abe88bcef3067a..10d860e0c4fd9c04ee274b32b1dcfe34d5c5d6d3 100755 (executable)
@@ -9,13 +9,12 @@ class HTMLBase( Resource ):
 
     def render_POST( self, request ):
         self.perform( request )
-        self.render_GET( request ) 
+        return self.render_GET( request )
         
     def render_GET( self, request ):
         self.write_TOP( request )
         self.write_BODY( request )
         self.write_BOTTOM( request )
-        request.finish()
         return ''
                 
     def write_BODY( self, request ):
index d0b7a77177d45de4e40b52f2246feedf1a6ea2c3..089d3f2e678d3763498055377988274c9aa17387 100755 (executable)
@@ -2,7 +2,9 @@ from xen.sv.util import *
 from xen.sv.HTMLBase import HTMLBase
 from xen.xend import sxp
 
-DEBUG = 1
+import re
+
+DEBUG = 0
 
 class Wizard( HTMLBase ):
 
@@ -27,17 +29,25 @@ class Wizard( HTMLBase ):
         else:
             currSheet = 0
             
-        op = getVar( 'op', request )
+        sheet = self.sheets[ currSheet ]( self.urlWriter )
+        
+        err = not sheet.validate( request )
+        
+        if not err:    
+            op = getVar( 'op', request )
         
-        if op == 'next':
-            currSheet += 1
-        elif op == 'prev':
-             currSheet -= 1
+            if op == 'next':
+               currSheet += 1
+            elif op == 'prev':
+               currSheet -= 1
              
-        sheet = self.sheets[ currSheet ]( self.urlWriter )    
-            
-        sheet.parseForm( request )
-        sheet.write_BODY( request )
+            sheet = self.sheets[ currSheet ]( self.urlWriter )
+        
+        if getVar( 'visited-sheet%s' % currSheet, request ):
+            sheet.write_BODY( request, err )
+        else:
+            sheet.write_BODY( request, False )
+
         
         request.write( "</td></tr><tr><td><table width='100%' border='0' cellspacing='0' cellpadding='0'><tr>" )
         request.write( "<td width='80%'></td><td width='20%' align='center'><p align='center'>" )
@@ -67,10 +77,10 @@ class Sheet( HTMLBase ):
         self.feilds = []
         self.title = title
         self.location = location
-        self.passback = "()"
+        self.passback = None
         
     def parseForm( self, request ):
-       do_not_parse = [ 'mod', 'op', 'sheet' ] 
+       do_not_parse = [ 'mod', 'op', 'sheet', 'passback' ] 
     
        passed_back = request.args
         
@@ -85,11 +95,6 @@ class Sheet( HTMLBase ):
         
         if DEBUG: print last_passback
         
-        try: 
-            del passed_back[ 'passback' ]
-        except:
-            pass
-        
         for (key, value) in passed_back.items():
             if key not in do_not_parse:
                 last_passback[ key ] = value[ len( value ) - 1 ]
@@ -98,37 +103,66 @@ class Sheet( HTMLBase ):
         
         if DEBUG: print self.passback
         
-    def write_BODY( self, request ):
+    def write_BODY( self, request, err ):
+    
+       if not self.passback: self.parseForm( request )
         
        request.write( "<p>%s</p>" % self.title )
     
-       previous_values = sxp2hash( string2sxp( self.passback ) ) #get the hash for quick reference
+       previous_values = ssxp2hash( string2sxp( self.passback ) ) #get the hash for quick reference
         
         request.write( "<table width='100%' cellpadding='0' cellspacing='1' border='0'>" )
         
        for (feild, control) in self.feilds:
             control.write_Control( request, previous_values.get( feild ) )
+            if err and not control.validate( previous_values.get( feild ) ):
+               control.write_Help( request )
             
         request.write( "</table>" )
             
         request.write( "<input type='hidden' name='passback' value=\"%s\"></p>" % self.passback )
         request.write( "<input type='hidden' name='sheet' value='%s'></p>" % self.location )
-        
+        request.write( "<input type='hidden' name='visited-sheet%s' value='True'></p>" % self.location )
+                
     def addControl( self, control ):
        self.feilds.append( [ control.getName(), control ] )
         
+    def validate( self, request ):
+    
+        if not self.passback: self.parseForm( request )
+            
+       check = True
+        
+        previous_values = ssxp2hash( string2sxp( self.passback ) ) #get the hash for quick reference
+       if DEBUG: print previous_values
+      
+       for (feild, control) in self.feilds:
+            if not control.validate( previous_values.get( feild ) ):
+                check = False
+                if DEBUG: print "> %s = %s" % (feild, previous_values.get( feild ))
+
+        return check
+        
 class SheetControl( HTMLBase ):
 
-    def __init__( self ):
+    def __init__( self, reg_exp = ".*" ):
         HTMLBase.__init__( self )
         self.name = ""
+        self.reg_exp = reg_exp 
         
     def write_Control( self, request, persistedValue ):
         request.write( "<tr colspan='2'><td>%s</td></tr>" % persistedValue )
         
-    def validate( self ):
-       return True
+    def write_Help( self, request ):
+        request.write( "<tr><td align='right' colspan='2'><p class='small'>Text must match pattern:" )
+        request.write( " %s</p></td></tr>" % self.reg_exp )
         
+    def validate( self, persistedValue ):
+       if persistedValue is None:
+            persistedValue = ""
+            
+        return not re.compile( self.reg_exp ).match( persistedValue ) is None
+
     def getName( self ):
        return self.name
         
@@ -137,19 +171,24 @@ class SheetControl( HTMLBase ):
         
 class InputControl( SheetControl ):
 
-    def __init__( self, name, defaultValue, humanText):
-        SheetControl.__init__( self )
+    def __init__( self, name, defaultValue, humanText,  reg_exp = ".*", help_text = "You must enter the appropriate details in this feild." ):
+        SheetControl.__init__( self, reg_exp )
         self.setName( name )
         
         self.defaultValue = defaultValue
         self.humanText = humanText
+        self.help_text = help_text
         
     def write_Control( self, request, persistedValue ):
        if persistedValue is None:
             persistedValue = self.defaultValue
         
-        request.write( "<tr><td width='50%%'><p>%s</p></td><td width='50%%'><input type='text' name='%s' value=\"%s\"></td></tr>" % (self.humanText, self.getName(), persistedValue) )
+        request.write( "<tr><td width='50%%'><p>%s</p></td><td width='50%%'><input size='40'type='text' name='%s' value=\"%s\"></td></tr>" % (self.humanText, self.getName(), persistedValue) )
 
+    def write_Help( self, request ):
+        request.write( "<tr><td align='right' colspan='2'><p class='small'>" )
+        request.write( " %s</p></td></tr>" % self.help_text )         
+        
 class TextControl( SheetControl ):
 
     def __init__( self, text ):
@@ -168,7 +207,63 @@ class SmallTextControl( SheetControl ):
     def write_Control( self, request, persistedValue ):
        request.write( "<tr><td colspan='2'><p class='small'>%s</p></tr></td>" % self.text )
         
-                 
-            
+class ListControl( SheetControl ):
+
+    def __init__( self, name, options, humanText ):
+       SheetControl.__init__( self )
+        self.setName( name )
+        self.options = options
+        self.humanText = humanText
+        
+    def write_Control( self, request, persistedValue ):
+        request.write( "<tr><td width='50%%'><p>%s</p></td><td width='50%%'>" % self.humanText )
+       request.write( "<select name='%s'>" % self.getName() )
+        for (value, text) in self.options:
+            if value == persistedValue:
+               request.write( "<option value='%s' selected>%s\n" % (value, text) )
+            else:
+                request.write( "<option value='%s'>%s\n" % (value, text) )
+        request.write( "</select></td></tr>" )
+
+    def validate( self, persistedValue ):
+        for (value, text) in self.options:
+            if value == persistedValue:
+                return True
+                
+        return False
+        
+class FileControl( InputControl ):
+
+    def __init__( self, name, defaultValue, humanText,  reg_exp = ".*", help_text = "You must enter the appropriate details in this feild." ):
+       InputControl.__init__( self, name, defaultValue, humanText )
+        
+    def validate( self, persistedValue ):
+        if persistedValue is None: return False
+        try:
+            open( persistedValue )
+            return True
+        except IOError, TypeError:
+            return False
     
+    def write_Help( self, request ):
+        request.write( "<tr><td colspan='2' align='right'><p class='small'>File does not exist: you must enter a valid, absolute file path.</p></td></tr>" )
+
+class TickControl( SheetControl ):
+
+    def __init__( self, name, defaultValue, humanText ):
+        SheetControl.__init__( self )
+        self.setName( name )
+        self.defaultValue = defaultValue
+        self.humanText = humanText
+        
+    def write_Control( self, request, persistedValue ):
+        request.write( "<tr><td width='50%%'><p>%s</p></td><td width='50%%'>" % self.humanText )
+        
+        if persistedValue == 'True':
+           request.write( "<input type='checkbox' name='%s' value='True' checked>" % self.getName() )
+        else:
+           request.write( "<input type='checkbox' name='%s' value='True'>" % self.getName() )
+            
+        request.write( "</select></td></tr>" )
+